﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Net;
using System.Net.Cache;
using System.Xml;

namespace CopyIt
{
    public partial class mainForm : Form
    {
        Parameters Parameters;
        const string fileconfig = "CopyIT.xml";
        private string lastReport = string.Empty;

        public mainForm()
        {
            InitializeComponent();
            CreateXSL();
        }

        private void CreateXSL()
        {
            if (!Directory.Exists("Logs"))
                Directory.CreateDirectory("Logs");

            if (File.Exists(@"CopyIT.xsl")) return;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] buffer = encoding.GetBytes(global::CopyIt.Properties.Resources.CopyIT);

            FileStream output = new FileStream(@"CopyIT.xsl", FileMode.Create);
            output.Write(buffer, 0, (int)buffer.Length);
            output.Close();
        }

        protected override void OnLoad(EventArgs e)
        {
            LoadParameters();
            Version curVer = new Version(Parameters.Version);
            this.Text = string.Format("CopyIt {0}.{1}", curVer.Major, curVer.Minor);
            if (Parameters.Pairs != null && Parameters.Pairs.Count > 0)
                lsbPairs.SelectedIndex = 0;
            DisplayPairsForm(lsbPairs.SelectedIndex);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            Parameters.Save(fileconfig);
        }

        private void LoadParameters()
        {
            this.Parameters = Parameters.Load(fileconfig);
            if (this.Parameters == null)
            {
                Parameters = new Parameters();
                Parameters.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
                Parameters.IncludeFilter = new List<string>();
                Parameters.IncludeFilter.Add("*.CR2;*.JPG");
                Parameters.ExcludeFilter = new List<string>();
                Parameters.ExcludeFilter.Add("thumbs.db");
                Parameters.Pairs = new List<PairsParameters>();
            }
            else
            {
                foreach (PairsParameters param in Parameters.Pairs)
                {
                    if (param.Guid.Equals(string.Empty))
                        param.Guid = Guid.NewGuid().ToString();
                    lsbPairs.AddNewItem(param.PairsName);
                }
            }

            // Aggiorno la versione nei parametri
            Parameters.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            PairsForm project = new PairsForm(Parameters.IncludeFilter, Parameters.ExcludeFilter,
                                                Parameters.IncludeFolder, Parameters.ExcludeFolder, true);
            //project.Closing+=new FormClosingEventHandler(project_Closing);
            project.PairsParameters = new PairsParameters();
            if (project.ShowDialog() == DialogResult.OK) 
            {
                int pos = lsbPairs.AddNewItem(project.PairsParameters.PairsName);
                Parameters.Pairs.Insert(pos, project.PairsParameters);
                lsbPairs.SelectedIndex = pos;

            }
        }

        void project_Closing(object sender, FormClosingEventArgs e)
        {
            PairsForm project = (PairsForm)sender;
            if (project.DialogResult == DialogResult.OK && project.IsNewPairs)
            {
                if (CheckExistsPairs(project.PairsParameters.PairsName))
                {
                    MessageBox.Show(string.Concat("L'abbinamento "+project.PairsParameters.PairsName+" esiste già"),"Attenzione", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    e.Cancel = true;
                }
            }
        }

        bool CheckExistsPairs(string pairs)
        {
            for (int t = 0; t < Parameters.Pairs.Count; t++)
                if (Parameters.Pairs[t].PairsName == pairs) return true;

            return false;
        }

        private void lsbPairs_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnDelete.Enabled = lsbPairs.SelectedIndex != lsbPairs.Items.Count - 1;
            DisplayPairsForm(lsbPairs.SelectedIndex);
        }

        private void lsbPairs_DoubleClick(object sender, EventArgs e)
        {
            if (lsbPairs.SelectedIndex != -1 && lsbPairs.SelectedIndex != lsbPairs.Items.Count -1)
            {
                PairsForm project = new PairsForm(Parameters.IncludeFilter, Parameters.ExcludeFilter, Parameters.IncludeFolder, Parameters.ExcludeFolder, false);
                project.PairsParameters = Parameters.Pairs[lsbPairs.SelectedIndex];
                if (project.ShowDialog() == DialogResult.OK)
                {
                    lsbPairs.Items[lsbPairs.SelectedIndex] = project.PairsParameters.PairsName;
                    DisplayPairsForm(lsbPairs.SelectedIndex);
                }
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lsbPairs.SelectedIndex != -1 && lsbPairs.SelectedIndex != lsbPairs.Items.Count - 1)
            {
                if (MessageBox.Show("Sei sicuro di voler cancellare l'abbinamento", "Cancellazione abbinamento", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Parameters.Pairs.RemoveAt(lsbPairs.SelectedIndex);
                    lsbPairs.SelectedIndex = lsbPairs.DeleteItem(lsbPairs.SelectedIndex);

                    DisplayPairsForm(lsbPairs.SelectedIndex);
                    btnDelete.Enabled = lsbPairs.SelectedIndex != lsbPairs.Items.Count - 1;
                }
            }
        }

        private void DisplayPairsForm(int pos)
        {
            UserControl uC = SearchDisplayed();
            if (pos == -1)
            {
                if (uC != null && uC.GetType() == typeof(DisplayPairs))
                    splitContainer1.Panel2.Controls.Remove(uC);
                ShowSplash();
            }
            else
                if (pos == lsbPairs.Items.Count - 1)
                    ShowAll(uC);
                else
                    ShowPairs(uC, pos);

            btnPreview.Enabled = pos >= 0;
        }

        UserControl SearchDisplayed()
        {
            foreach (Control ctrl in splitContainer1.Panel2.Controls)
                if (ctrl.GetType() != typeof(Panel))
                    return (UserControl)ctrl;

            return null;
        }

        void ShowSplash()
        {
            DisplaySplash dS = new DisplaySplash();
            splitContainer1.Panel2.Controls.Add(dS);
            dS.LinkClicked += new EventHandler(dS_LinkClicked);
            btnPreview.Enabled = false;
        }

        void ShowAll(UserControl uC)
        {
            if (uC != null && uC.GetType() == typeof(DisplayAll))
            {
                DisplayAll dP = (DisplayAll)uC;
                dP.SetParams(Parameters.Pairs);
            }
            else
            {
                splitContainer1.Panel2.Controls.Remove(uC);
                DisplayAll dA = new DisplayAll();
                splitContainer1.Panel2.Controls.Add(dA);
                dA.BringToFront();
                dA.Dock = DockStyle.Fill;
                dA.SetParams(Parameters.Pairs);
                dA.ItemChecked += new ItemCheckedEventHandler(dA_ItemChecked);
            }
        }

        void ShowPairs(UserControl uC, int pos)
        {
            if (uC != null && uC.GetType() == typeof(DisplayPairs))
            {
                DisplayPairs dP = (DisplayPairs)uC;
                dP.SetParams(Parameters.Pairs[pos]);
            }
            else
            {
                splitContainer1.Panel2.Controls.Remove(uC);
                DisplayPairs dP = new DisplayPairs();
                dP.SetParams(Parameters.Pairs[pos]);
                dP.InvertSourceDest += new EventHandler(dP_InvertSourceDest);
                splitContainer1.Panel2.Controls.Add(dP);
            }
        }

        void dP_InvertSourceDest(object sender, EventArgs e)
        {
            int pos = lsbPairs.SelectedIndex;
            string tmp = Parameters.Pairs[pos].SourceFolder;
            Parameters.Pairs[pos].SourceFolder = Parameters.Pairs[pos].DestFolder;
            Parameters.Pairs[pos].DestFolder = tmp;
            ((DisplayPairs)sender).SetParams(Parameters.Pairs[pos]);
        }   

        void dA_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            Parameters.Pairs[e.Item.Index].Checked = e.Item.Checked;
        }

        void dS_LinkClicked(object sender, EventArgs e)
        {
            btnNew_Click(sender, e);
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            //if (splitContainer1.Panel2.Controls.Count == 2)
            //    splitContainer1.Panel2.Controls[1].Visible = false;

            UserControl uC = SearchDisplayed();

            DisplayPreview dP = new DisplayPreview();
            dP.Close += new EventHandler(dP_Close);
            dP.Copy += new EventHandler(dP_Copy);
            splitContainer1.Panel2.Controls.Add(dP);
            dP.BringToFront();
            dP.Dock = DockStyle.Fill;
            EnableDisablePanel(false);

            if (lsbPairs.SelectedIndex == lsbPairs.Items.Count - 1)
            {
                DisplayAll dA = null;
                if (uC.GetType() == typeof(DisplayAll))
                    dA = uC as DisplayAll;

                if (dA!=null)
                {
                    dP.Sincronize(dA.Params);
                }
            }
            else
                dP.Sincronize(Parameters.Pairs[lsbPairs.SelectedIndex]);
        }

        void dP_Copy(object sender, EventArgs e)
        {
            DisplayPreview dP = null;
            UserControl uC = SearchDisplayed();
            if (uC.GetType() == typeof(DisplayPreview))
                dP = uC as DisplayPreview;

            DisplayCopier dC = new DisplayCopier(dP.Tree, Parameters.Pairs);
            dC.Close += new EventHandler(dC_Close);
            dC.Report += new EventHandler(dC_Report);
            splitContainer1.Panel2.Controls.Add(dC);
            dC.BringToFront();
            dC.Dock = DockStyle.Fill;

            dC.Start(out lastReport);
        }

        void dC_Report(object sender, EventArgs e)
        {
            DisplayReport dR = new DisplayReport(lastReport);
            dR.Close += new EventHandler(dR_Close);
            splitContainer1.Panel2.Controls.Add(dR);
            dR.BringToFront();
            dR.Dock = DockStyle.Fill;
        }

        void dP_Close(object sender, EventArgs e)
        {
            splitContainer1.Panel2.Controls.Remove(sender as DisplayPreview);
            lsbPairs.Enabled = true;
            if (splitContainer1.Panel2.Controls.Count == 2)
                splitContainer1.Panel2.Controls[1].Visible = true;

            EnableDisablePanel(true);
        }

        void dR_Close(object sender, EventArgs e)
        {
            splitContainer1.Panel2.Controls.Remove(sender as DisplayReport);
        }

        void dC_Close(object sender, EventArgs e)
        {
            splitContainer1.Panel2.Controls.Remove(sender as DisplayCopier);

            DisplayPreview dP = null;
            UserControl uC = SearchDisplayed();
            if (uC.GetType() == typeof(DisplayPreview))
                dP = uC as DisplayPreview;

            if (dP != null)
                dP_Close(dP, e);
        }

        void EnableDisablePanel(bool status)
        {
            btnPreview.Enabled = status;
            btnNew.Enabled = status;
            btnDelete.Enabled = status == false ? false : lsbPairs.SelectedIndex != (lsbPairs.Items.Count -1);
            lsbPairs.Enabled = status;
        }

        private void tsmExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void tsmInfo_Click(object sender, EventArgs e)
        {
            AboutBox aBox = new AboutBox();
            aBox.ShowDialog();
        }

        private void CheckForNewVersion(bool fromMenu)
        {
            string xmlURL = "http://www.maurorogledi.it/PusherSoftware/CopyIt/appl_version.xml";
            Application.DoEvents();

            WebClient client = new WebClient();
            client.Proxy.Credentials = CredentialCache.DefaultCredentials;
            client.CachePolicy = new System.Net.Cache.RequestCachePolicy(RequestCacheLevel.Reload);
            Version newVersion;
            string urlDownload;

            try
            {
                Stream strm = client.OpenRead(xmlURL);
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(strm);

                XmlNode xNode = xDoc.SelectSingleNode("/application/version");
                newVersion = new Version(xNode.InnerText);

                xNode = xDoc.SelectSingleNode("/application/url");
                urlDownload = xNode.InnerText;
                strm.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Ci sono problemi di accesso al sito del produttore", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Version curVersion = new Version(Parameters.Version);
            if (curVersion.CompareTo(newVersion) < 0)
            {
                if (MessageBox.Show(string.Format("E' presente sul sito la versione  la versione {0}.\nLa vuoi scaricare ?", newVersion.ToString()), Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    System.Diagnostics.Process.Start(urlDownload);
            }
            else
                if (fromMenu)
                    MessageBox.Show("E' gia installata l'ultima versione disponibile", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void tsmCheckNew_Click(object sender, EventArgs e)
        {
            CheckForNewVersion(true);
        }

        private void tsmChangeDevice_Click(object sender, EventArgs e)
        {
            DeviceForm dF = new DeviceForm(ref Parameters.Pairs);
            if (dF.DialogResult != DialogResult.Cancel && dF.ShowDialog(this) == DialogResult.OK)
                DisplayPairsForm(lsbPairs.SelectedIndex);
        }
    }
}
